using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp;
using Volo.Abp.Autofac;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.Sqlite;
using Volo.Abp.Modularity;
using Volo.Abp.Testing;

namespace Matrix.Configuration
{
    /// <summary>
    /// 应用层测试模块
    /// </summary>
    [DependsOn(
        typeof(AbpAutofacModule),
        typeof(AbpTestBaseModule),
        typeof(AbpEntityFrameworkCoreModule),
        typeof(AbpEntityFrameworkCoreSqliteModule),
        typeof(MatrixConfigurationDomainModule),
        typeof(MatrixConfigurationApplicationModule),
        typeof(MatrixConfigurationEntityFrameworkCoreModule)
    )]
    public class MatrixConfigurationApplicationTestModule : AbpModule
    {
        private SqliteConnection _connection = null!;

        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            // 配置测试数据库
            ConfigureInMemorySqlite(context);

            // 配置测试选项
            context.Services.AddAlwaysAllowAuthorization();

            Configure<AbpMultiTenancyOptions>(options =>
            {
                options.IsEnabled = true;
            });
        }

        private void ConfigureInMemorySqlite(ServiceConfigurationContext context)
        {
            _connection = CreateDatabaseAndGetConnection();

            context.Services.AddAbpDbContext<MatrixConfigurationDbContext>(options =>
            {
                options.AddDefaultRepositories(includeAllEntities: true);
            });

            Configure<AbpDbContextOptions>(options =>
            {
                options.Configure(abpDbContextConfigurationContext =>
                {
                    abpDbContextConfigurationContext.DbContextOptions.UseSqlite(_connection);
                });
            });
        }

        private SqliteConnection CreateDatabaseAndGetConnection()
        {
            var connection = new SqliteConnection("Data Source=:memory:");
            connection.Open();

            var options = new DbContextOptionsBuilder<MatrixConfigurationDbContext>()
                .UseSqlite(connection)
                .Options;

            using (var context = new MatrixConfigurationDbContext(options))
            {
                context.Database.EnsureCreated();
            }

            return connection;
        }

        public override void OnApplicationShutdown(ApplicationShutdownContext context)
        {
            _connection?.Dispose();
        }
    }
}